#ifndef IDevice_H
#define IDevice_H

#include <QDateTime>
#include <QDebug>
#include <QObject>

class QTimer;

#include "ConstData.h"
#include "ConstNames.h"

// 数据结构保留在头文件
struct DeviceData {
    // 通用字段
    quint16 status = 8;  // 默认空闲
    quint16 faultCode = 0;
    QDateTime datetime = QDateTime();

    // 常规设备字段
    float analyze_preResult = 0;
    float analyze_lastResult = 0;
    float inspect_zero_lastResult = 0;
    float inspect_std_lastResult = 0;
    float cali1_lastResult = 0;
    float cali2_lastResult = 0;
    float cali1_absorbance = 0;
    float cali2_absorbance = 0;
    float cali_std1_conc = 0;    // 标一浓度
    float cali_std2_conc = 0;    // 标二浓度
    float inspect_std_conc = 0;  // 核查标样浓度
    QDateTime inspect_zero_lastDate = QDateTime();
    QDateTime inspect_std_lastDate = QDateTime();
    QDateTime cali1_lastDate = QDateTime();
    QDateTime cali2_lastDate = QDateTime();

    // 预处理设备字段
    QVector<quint16> valveStatus;
    float pressure_lastResult = 0;
    quint16 ycl_step_state = 0;
};

// 设备接口类
class IDevice : public QObject
{
    Q_OBJECT
public:
    virtual ~IDevice() = default;
    /************************************通用方法**********************************/
    QString getDeviceName() const { return m_deviceName; }
    DeviceType getDeviceType() const { return m_deviceAttribute.deviceType; }
    DeviceAttribute getDeviceAttribute() const { return m_deviceAttribute; }
    DeviceData getDeviceData() const { return m_deviceData; }
    const QMap<QString, quint16>& getOperateMap() const { return m_operateMap; }
    const QMap<quint16, QString>& getStatusMap() const { return m_statusMap; }
    const QMap<quint16, QString>& getErrorMap() const { return m_errorMap; }
    const QVariantMap& getConfigMap() const { return m_configMap; }
    QString getStatusName(quint16 status) const { return m_statusMap.value(status, "未知状态"); }
    QString getErrorName(quint16 error) const { return m_errorMap.value(error, "未知错误"); }
    QVariant getConfigByName(const QString& key) const { return m_configMap.value(key, 0.0f); }
    bool isIdle() const { return m_isIdle; }
    bool hasError() const
    {
        return m_deviceData.faultCode != m_errorMap.key(ErrorNames::COMMON_ERROR_NONE, 0);
    }
    bool isEnabled();
    void startDataMonitoring();
    void stopDataMonitoring();
    void control(quint16 addr, quint16 data);
    /************************************通用方法**********************************/

    /************************************子类实现**********************************/
    virtual void setDeviceTime(const QDateTime& datetime) {};                   // 空实现
    virtual void control(quint16 optCode) { qDebug() << "IDevice::control"; };  // 空实现
    virtual void stop()
    {
        // TODO 有的设备还未完成该功能；可以重新实现也可以映射操作命令COMMON_STOP
        if (isEnabled()) control(m_operateMap.value(OperationNames::COMMON_STOP));
    }
    virtual bool saveDeviceConfig(const QVariantMap& configMap)
    {
        qDebug() << "IDevice::saveDeviceConfig";
        return false;  // 默认返回false，子类可重载实现
    }
    /************************************子类实现**********************************/
signals:
    void deviceDataChanged(const DeviceData& deviceData);
    void commStatusChanged(bool commStatus);
    void errorOccurred(const QString& errorMessage);
    void measurementOutOfRange(const QString& deviceName, float value, float lowerLimit,
                               float upperLimit);  // 测量值超出范围信号

protected slots:
    virtual void onGetDeviceData() = 0;

protected:
    explicit IDevice(const QString& deviceName, QObject* parent = nullptr);
    QString m_deviceName;
    DeviceAttribute m_deviceAttribute;
    QTimer* m_deviceDataTimer;
    DeviceData m_deviceData;
    QMap<QString, quint16> m_operateMap;  // 每个设备的操作映射
    QMap<quint16, QString> m_statusMap;   // 每个设备的状态映射
    QMap<quint16, QString> m_errorMap;    // 每个设备的错误码映射
    QVariantMap m_configMap;              // 每个设备的配置映射
    bool m_isIdle = true;
    struct {
        bool controlBusy = false;
        bool dataBusy = false;
    } m_busyFlags;
    quint16 m_lastFaultCode = 0;
};
#endif  // IDevice_H